﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LoA.Shared.Interfaces;
using Microsoft.Xna.Framework;

namespace LoA.CameraEngine.Entities {
	internal abstract class CameraProcessorBase : ICameraProcessor {
		private float aspectRatio;
		private float fieldOfView;
		private float nearPlaneDistance;
		private float farPlaneDistance;

		public CameraProcessorBase( ) {
			this.aspectRatio = 4.0f / 3.0f;
			this.fieldOfView = MathHelper.ToRadians(45.0f);
			this.nearPlaneDistance = 0.5f;
			this.farPlaneDistance = 10000.0f;
		}

		/// <summary>
		/// Perspective aspect ratio. Default value should be overriden by application.
		/// </summary>
		public float AspectRatio {
			get { return aspectRatio; }
			set {
				aspectRatio = value;
				this.UpdateProjection( );
			}
		}

		/// <summary>
		/// Perspective field of view.
		/// </summary>
		public float FieldOfView {
			get { return fieldOfView; }
			set {
				fieldOfView = value;
				this.UpdateProjection( );
			}
		}

		/// <summary>
		/// Distance to the near clipping plane.
		/// </summary>
		public float NearPlaneDistance {
			get { return nearPlaneDistance; }
			set {
				nearPlaneDistance = value;
				this.UpdateProjection( );
			}
		}

		/// <summary>
		/// Distance to the far clipping plane.
		/// </summary>
		public float FarPlaneDistance {
			get { return farPlaneDistance; }
			set {
				farPlaneDistance = value;
				this.UpdateProjection( );
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public Matrix ProjectionMatrix { get; protected set; }

		/// <summary>
		/// 
		/// </summary>
		public Matrix ViewMatrix { get; protected set; }

		/// <summary>
		/// 
		/// </summary>
		/// <param name="gameTime"></param>
		/// <param name="inputEngine"></param>
		public abstract void Update(GameTime gameTime, IInput inputEngine);

		/// <summary>
		/// 
		/// </summary>
		/// <param name="Height"></param>
		/// <param name="Width"></param>
		public virtual void UpdateAspectRatio(double Height, double Width) {
			this.AspectRatio = (float)(Width / Height);
		}

		/// <summary>
		/// 
		/// </summary>
		protected virtual void UpdateProjection( ) {
			ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(FieldOfView, AspectRatio, NearPlaneDistance, FarPlaneDistance);
		}
	}
}
